---
id: 传输优化
title: 传输优化  
---

## gzip 优化
作为在 RFC 2016 中规定的三种标准HTTP压缩格式之一，开启会在打包出的资源处额外增加同一文件的 *.gz 格式。  
优点：对传输资源进行体积压缩，一般对纯文本内容可压缩到原大小的40%, 可高达90%

将资源放到服务器，且服务器配置支持 gzip 后，  
客户端请求资源的 Request Headers 中若有 Accept-Encoding: gzip, deflate 则会请求 gzip 文件，  
服务端的 Response Headers 中则会有 Content-Encoding: gzip

如果客户端和服务端任意一方不支持 gzip，则会请求正常的 html/css/js 文件。

- webpack 配置方法  

`npm install compression-webpack-plugin --save-dev`  

```js 
// webpack.config.js

const CompressionPlugin = require("compression-webpack-plugin")

module.exports = {
  plugins: [
    new CompressionPlugin({
        test: /\.js$|\.html$|\.css$/u,
        threshold: 4096, // 超过 4kb 压缩
      })
  ]
}
```

```js 
// vue.config.js

const CompressionPlugin = require("compression-webpack-plugin")

module.exports = {
  module.exports = {
  configureWebpack: {
    plugins: [
      new CompressionPlugin({
        test: /\.js$|\.html$|\.css$/u,
        threshold: 4096, // 超过 4kb 压缩
      })
    ],
  }
}
}
```

:::tip
如果运行时报错：TypeError:Cannot read properties of undefined(reading 'tapPromist')    
是插件版本太高了，调低一点即可。
:::
## 启用Keep Alive(持久连接)  
HTTP 持久性连接（也称为 HTTP keep-alive或 HTTP 连接重复使用）是一种概念，允许单个 TCP 连接发送和接收多个 HTTP 请求/响应，而不是为每个请求/响应对打开新连接。 

Apigee 使用持久性连接与后端服务进行通信。默认情况下，连接保持活动状态 60 秒。也就是说，如果连接在连接池中的空闲时间超过 60 秒，则该连接会关闭。

keep-alive 超时期限可通过 API 代理的 TargetEndpoint 配置中指定的名为 keepalive.timeout.millis 的属性进行配置。例如，对于 TargetEndpoint 中的特定后端服务，您可以将 keep-live 时间段设置为 30 秒。

<!-- - 影响
    - 增加 API 请求的总体响应时间，因为 Apigee 必须打开新连接并对每条新请求执行 SSL 握手。
    - 在高流量条件下，连接可能会耗尽，因为将连接撤销到系统需要一些时间。 -->

- 最佳做法
    - 后端服务应按照 HTTP 1.1 标准遵守和处理 HTTP 持久性连接。
    - 如果后端服务能够处理持久性（keep-alive）连接，则应使用 Connection:keep-alive 标头做出响应。
    - 如果后端服务无法处理持久性连接，则应使用 Connection:close 标头做出响应。

[google 介绍 keep-alive](https://cloud.google.com/apigee/docs/api-platform/antipatterns/disable-persistent-connections?hl=zh-cn&cloudshell=false)
HTTP Keep-Alive 是 Web 服务器的一项功能，它允许客户端保持连接打开。它也被称为“持久连接”。


HTTP Keep-Alive 背后的想法是防止连接超时和关闭，这将需要客户端重新连接。这为用户和网站服务器节省了时间。


- 一个持久的TCP连接，节省了连接创建时间
- Nginx默认开启keep alive

curl -v http: //127.0.0.1:80

- 响应头 Response Headers

connection: keep-alive

## HTTP缓存
- 提高重复访问时资源加载的速度

### Cache-Control/Expires
### Last-Modified + If-Modified-Since
### Etag + If-None-Match

- Service Workers 作用
- 加速重复访问
- 离线支持
- 注意:延长了首屏时间，但页面总加载时间减少
- 只能在localhost或https下使用


## HTTP/2的提升
查看方法google devtool network面板protocol

- HTTP/2优势
    - 二进制传输
    - 请求响应多路复用
    - Server push

- 生成自验证证书
    - openssl genrsa -des3 -passout pass:x -out server.pass.key 2048
    - openssl-rsa-passin pass:x -in server.pass.key -out server.key
    - openssl req -new -key server.key -out server.csr
    - openssl x509 -req -sha256 -days 3650 -in server.csr -out server.crt
    - 访问浏览器会拦截：跳过拦截：键盘输入thisisunsafe


## 服务端渲染SSR
- 加速首屏加载
- 更好的SEO
- React SSR 可以基于Next.js


## 优化资源加载的顺序
查看资源加载顺序方法google devtool network面板priority
- 使用preload, prefetch调整优先级
- Preload：提前加载较晚出现，但对当前页面非常重要的资源
- Prefetch：提前加载后继路由需要的资源，优先级低
```html
<html>
<head>
<Link rel="preload" href="img/img.svg" as="image" >
<Link rel="preload" href="img/img.woff2" as="font" type="font/woff2" crossorigin="anonymous">
</head>
</html>

```
- webpack 配置方法

```js 
import(/* webpackPrefetch: true * /'LoginModal");
```

- 动态设置Preload



## 预渲染页面
- 预渲染的作用
    - 大型单页应用的性能瓶颈：JS下载＋解析＋执行
    - SSR的主要问题：牺牲TTFB来补救First Paint；实现复杂
    - Pre-rendering 打包时提前渲染页面，没有服务端参与


- [react-snap](http://github.com/stereobooster/react-snap)
    - 配置postbuild
    - 使用ReactDoM.hydrate( )
    - 内联样式，避免明显的FOUC（样式闪动）

```js 
//package.json
script:{
    "postbuild":"react-snap"
}

```